package cn.yimu.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 
 * the package contains two parts:
 * 1. blank-time's judgement and creation
 * 2. convertion bwtween time and string
 * 
 * note: time include date and calendar
 * 
 * @author wangchuanzheng
 *
 */
public abstract class TimeUtil {
	
	public final static int YEAR_OF_BLANK_CALENDAR = 1970;
	public final static int MONTH_OF_BLANK_CALENDAR = Calendar.JANUARY;
	public final static int DAY_OF_BLANK_CALENDAR = 1;
	public final static int HOUR_OF_BLANK_CALENDAR = 0;
	public final static int MINUTE_OF_BLANK_CALENDAR = 0;
	public final static int SECOND_OF_BLANK_CALENDAR = 0;
	

	public final static String DEFAULT_PATTERN_OF_DATE = "yyyy-MM-dd";
	public final static String DEFAULT_PATTERN_OF_TIME = "HH:mm:ss";
	public final static String DEFAULT_PATTERN_OF_DATE_AND_TIME = String.format("%s %s", DEFAULT_PATTERN_OF_DATE, DEFAULT_PATTERN_OF_TIME);

	public static Calendar createBlankCalendar() {
		Calendar result = Calendar.getInstance();
		result.set(YEAR_OF_BLANK_CALENDAR, MONTH_OF_BLANK_CALENDAR, DAY_OF_BLANK_CALENDAR, HOUR_OF_BLANK_CALENDAR, MINUTE_OF_BLANK_CALENDAR, SECOND_OF_BLANK_CALENDAR);
		
		return result;
	} 

	public static Date createBlankDate() {
		Calendar blankCalendar = createBlankCalendar();
		Date result = blankCalendar.getTime();
		
		return result;
	}

	public static boolean isBlankCalendar(final Calendar target) {
		assert target != null;
		
		int year = target.get(Calendar.YEAR);
		int month = target.get(Calendar.MONTH);
		int day = target.get(Calendar.DAY_OF_MONTH);
		int hour = target.get(Calendar.HOUR_OF_DAY);
		int minute = target.get(Calendar.MINUTE);
		int second = target.get(Calendar.SECOND);
		
		if (year != YEAR_OF_BLANK_CALENDAR)
			return false;
		if (month != MONTH_OF_BLANK_CALENDAR)
			return false;
		if (day != DAY_OF_BLANK_CALENDAR)
			return false;
		if (hour != HOUR_OF_BLANK_CALENDAR)
			return false;
		if (minute != MINUTE_OF_BLANK_CALENDAR)
			return false;
		if (second != SECOND_OF_BLANK_CALENDAR)
			return false;
		
		return true;
	}
	
	public static boolean isBlankDate(final Date target) {
		assert target != null;

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(target);
		
		boolean result = isBlankCalendar(calendar);
		
		return result;
	}
	
	public static String parseCalendarToString(final Calendar target) {
		assert target != null;

		Date date = target.getTime();
		String result = parseDateToString(date);
		
		return result;
	}
	
	public static String parseDateToString(final Date target) {
		assert target != null;

		SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_PATTERN_OF_DATE_AND_TIME);
		String result = sdf.format(target);
		
		return result;
	}
	
	public static String parseCalendarToString(final Calendar target, final String pattern) {
		assert target != null;
		assert pattern != null;
		
		
		Date date = target.getTime();
		String result = parseDateToString(date, pattern);
		
		return result;
	}
	
	public static String parseDateToString(final Date target, final String pattern) {
		assert target != null;
		assert pattern != null;
		
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		String result = sdf.format(target);
		
		return result;
	}

	public static Calendar parseStringToCalendar(final String target) throws ParseException {
		assert target != null;
		
		Date date = parseStringToDate(target);
		Calendar result = Calendar.getInstance();
		result.setTime(date);
		
		return result;
	}
	
	public static Date parseStringToDate(final String target) throws ParseException {
		assert target != null;
		
		SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_PATTERN_OF_DATE_AND_TIME);
		Date result = sdf.parse(target);
		
		return result;
	}
	
	public static Calendar parseStringToCalendar(final String target, final String pattern) throws ParseException {
		assert target != null;
		assert pattern != null;
		
		Date date = parseStringToDate(target, pattern);
		Calendar result = Calendar.getInstance();
		result.setTime(date);
		
		return result;
	}
	
	public static Date parseStringToDate(final String target, final String pattern) throws ParseException {
		assert target != null;
		assert pattern != null;
		
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		Date result = sdf.parse(target);
		
		return result;
	}
	
	public static boolean compareDate(final Calendar target1, final Calendar target2) {
		assert target1 != null;
		assert target2 != null;
		
		if(target1.get(Calendar.YEAR) != target2.get(Calendar.YEAR))
			return false;
		
		if(target1.get(Calendar.MONTH) != target2.get(Calendar.MONTH))
			return false;
		
		if(target1.get(Calendar.DAY_OF_MONTH) != target2.get(Calendar.DAY_OF_MONTH))
			return false;
		
		return true;
	}
	
	public static boolean compareDate(final Date target1, final Date target2) {
		assert target1 != null;
		assert target2 != null;

		Calendar c1 = Calendar.getInstance();
		c1.setTime(target1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(target2);
		
		boolean result = compareDate(c1, c1);
		return result;
	}
	
	public static boolean compareTime(final Calendar target1, final Calendar target2) {
		assert target1 != null;
		assert target2 != null;

		if(target1.get(Calendar.HOUR_OF_DAY) != target2.get(Calendar.HOUR_OF_DAY))
			return false;
		
		if(target1.get(Calendar.MINUTE) != target2.get(Calendar.MINUTE))
			return false;
		
		if(target1.get(Calendar.SECOND) != target2.get(Calendar.SECOND))
			return false;
		
		return true;
	}
	
	public static boolean compareTime(final Date target1, final Date target2) {
		assert target1 != null;
		assert target2 != null;

		Calendar c1 = Calendar.getInstance();
		c1.setTime(target1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(target2);
		
		boolean result = compareTime(c1, c1);
		return result;
	}

	public static boolean compareDateAndTime(final Calendar target1, final Calendar target2) {
		assert target1 != null;
		assert target2 != null;

		if(!compareDate(target1, target2))
			return false;
		
		if(!compareTime(target1, target2))
			return false;
		
		return false;
	}
	
	public static boolean compareDateAndTime(final Date target1, final Date target2) {
		assert target1 != null;
		assert target2 != null;

		Calendar c1 = Calendar.getInstance();
		c1.setTime(target1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(target2);
		
		boolean result =  compareDateAndTime(c1, c2);
		return result;
	}
	
	
}
